package com.gxa.springboot251.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gxa.springboot251.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.Field;
import java.util.List;

// 通用的Service的实现类设计注意事项:
// 1. 在接口和实现类上都需要<T>
// 2. 不希望该类被实例化
// 3. 不需要@Service
// 4. 需要实现所有BaseService的方法
@Transactional(rollbackFor = Throwable.class,propagation = Propagation.SUPPORTS)
public abstract class BaseServiceImpl<T> implements BaseService<T> {

    // 如何选择自动装配的注解?
    // 当子类继承的时候,需要: Mapper<User> Mapper<Admin>
    // Spring在4之后提供一种注入机制:  泛型依赖注入
    @Autowired
    Mapper<T> mapper;

    @Override
    public T selectById(Integer id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public List<T> select(T t) {
        return mapper.select(t);
    }

    @Override
    public List<T> selectByLike(T t) throws IllegalAccessException {
        Example example = new Example(t.getClass());
        Example.Criteria criteria = example.createCriteria();
//        通过t反射得到字段列表,遍历获取非空字段
        Class<?> clazz = t.getClass();
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Object value = declaredField.get(t);
            String name = declaredField.getName();
            if(value!=null){
                criteria.andLike(name,value.toString());
            }
        }
        List<T> list = mapper.selectByExample(example);
        return list;
    }

    @Override
    public List<T> selectAll() {
        return mapper.selectAll();
    }

    @Override
    /**
     * @param t 可选的带有查询条件的对象,两种情况: 一个t或没有
     */
    public PageInfo<T> selectByPage(Integer page, Integer size, T... t) {

        PageHelper.startPage(page,size);
        List<T> select = null;
        if(t.length>0){
            select = mapper.select(t[0]);
        }else{
            select = mapper.selectAll();
        }
        return PageInfo.of(select);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void add(T t) {
        mapper.insert(t);
    }

    @Override
    public void updateById(T t) {

    }

    @Override
    public void deleteById(Integer id) {

    }
}
